package com.ruoyi.web.controller.iot;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.EasyExcelUtils;
import com.ruoyi.iot.domain.dto.DeviceElectricalLedgerExportDTO;
import com.ruoyi.iot.domain.entity.DeviceElectricalWindow;
import com.ruoyi.iot.domain.query.DeviceElectricalWindowQuery;
import com.ruoyi.iot.service.DeviceElectricalWindowService;
import com.ruoyi.iot.service.HostDeviceMetricsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 设备电气台账控制器
 */
@Tag(name = "设备电气台账（DeviceElectricalWindow）接口")
@RestController
@RequestMapping("/iot/device-electrical-ledger")
public class DeviceElectricalLedgerController extends BaseController {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final List<Field> EXPORT_FIELDS;
    private static final List<List<String>> EXPORT_HEAD;

    static {
        List<Field> fields = new ArrayList<>();
        for (Field field : DeviceElectricalLedgerExportDTO.class.getDeclaredFields()) {
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            field.setAccessible(true);
            fields.add(field);
        }
        EXPORT_FIELDS = Collections.unmodifiableList(fields);
        EXPORT_HEAD = Collections.unmodifiableList(EXPORT_FIELDS.stream()
            .map(DeviceElectricalLedgerController::buildHeaderCell)
            .collect(Collectors.toList()));
    }

    private final DeviceElectricalWindowService deviceElectricalWindowService;
    private final HostDeviceMetricsService hostDeviceMetricsService;

    public DeviceElectricalLedgerController(DeviceElectricalWindowService deviceElectricalWindowService,
                                            HostDeviceMetricsService hostDeviceMetricsService) {
        this.deviceElectricalWindowService = deviceElectricalWindowService;
        this.hostDeviceMetricsService = hostDeviceMetricsService;
    }

    /**
     * 分页查询设备电气台账数据
     *
     * @param query 查询条件
     * @return 电气台账分页数据
     */
    @Operation(summary = "分页查询设备电气台账数据", tags = "设备电气台账接口")
    @GetMapping("/list")
    public TableDataInfo list(DeviceElectricalWindowQuery query) {
        startPage();
        List<DeviceElectricalWindow> list = deviceElectricalWindowService.list(query);

        if(CollectionUtils.isEmpty(list)){
            query.setDeviceId(hostDeviceMetricsService.findDeviceIdByDeviceKgId(query.getDeviceId()));
            list = deviceElectricalWindowService.list(query);
        }

        Map<String, String> deviceNameIndex = buildDeviceNameIndex();
        List<DeviceElectricalLedgerExportDTO> exportList = list.stream()
            .map(item -> DeviceElectricalLedgerExportDTO.from(item, deviceNameIndex.get(item.getDeviceId())))
            .collect(Collectors.toList());
        return getDataTable(exportList);
    }

    /**
     * 导出设备电气台账
     *
     * @param response HTTP响应
     * @param query 查询条件
     */
    @Operation(summary = "导出设备电气台账数据", tags = "设备电气台账接口")
    @Log(title = "设备电气台账", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DeviceElectricalWindowQuery query) {
        List<DeviceElectricalWindow> list = deviceElectricalWindowService.list(query);
        Map<String, String> deviceNameIndex = buildDeviceNameIndex();
        List<DeviceElectricalLedgerExportDTO> exportList = list.stream()
            .map(item -> DeviceElectricalLedgerExportDTO.from(item, deviceNameIndex.get(item.getDeviceId())))
            .collect(Collectors.toList());
        List<List<Object>> rows = buildExportRows(exportList);
        EasyExcelUtils.write(response, "设备电气台账", "设备电气台账", EXPORT_HEAD, rows);
    }

    /**
     * 构建表头单元格
     *
     * @param field 字段信息
     * @return 表头集合
     */
    private static List<String> buildHeaderCell(Field field) {
        Schema schema = field.getAnnotation(Schema.class);
        String header = (schema != null && StringUtils.isNotBlank(schema.description()))
            ? schema.description()
            : field.getName();
        return Collections.singletonList(header);
    }

    /**
     * 构建导出数据行
     *
     * @param dataList 导出数据
     * @return 数据行
     */
    private List<List<Object>> buildExportRows(List<DeviceElectricalLedgerExportDTO> dataList) {
        List<List<Object>> rows = new ArrayList<>(dataList.size());
        for (DeviceElectricalLedgerExportDTO dto : dataList) {
            List<Object> row = new ArrayList<>(EXPORT_FIELDS.size());
            for (Field field : EXPORT_FIELDS) {
                row.add(extractValue(dto, field));
            }
            rows.add(row);
        }
        return rows;
    }

    /**
     * 构建设备名称索引
     *
     * @return 设备ID与名称映射
     */
    private Map<String, String> buildDeviceNameIndex() {
        List<Map<String, Object>> devices = hostDeviceMetricsService.queryAllMainCabinetMetrics();
        Map<String, String> index = new HashMap<>(devices.size() * 2);
        for (Map<String, Object> device : devices) {
            String deviceName = toStringSafe(device.get("device_name"));
            if (StringUtils.isBlank(deviceName)) {
                continue;
            }
            String deviceId = toStringSafe(device.get("device_id"));
            String deviceKgId = toStringSafe(device.get("device_kg_id"));
            if (StringUtils.isNotBlank(deviceId)) {
                index.put(deviceId, deviceName);
            }
            if (StringUtils.isNotBlank(deviceKgId)) {
                index.put(deviceKgId, deviceName);
            }
        }
        return index;
    }

    /**
     * 空安全获取字符串
     *
     * @param value 原始对象
     * @return 字符串
     */
    private String toStringSafe(Object value) {
        return value == null ? null : value.toString();
    }

    /**
     * 提取导出字段值
     *
     * @param dto 导出对象
     * @param field 字段
     * @return 字段值
     */
    private Object extractValue(DeviceElectricalLedgerExportDTO dto, Field field) {
        try {
            Object value = field.get(dto);
            if (value instanceof LocalDateTime) {
                return ((LocalDateTime) value).format(DATE_TIME_FORMATTER);
            }
            return value;
        } catch (IllegalAccessException ex) {
            return null;
        }
    }
}
